」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > Go 和 Python 之間的 gRPC 通信

Go 和 Python 之間的 gRPC 通信

發佈於2024-11-08
瀏覽:823

gRPC Communication Between Go and Python

gRPC 是一个功能强大、高性能的远程过程调用 (RPC) 框架,尽管不如 REST 常用,但在某些场景中提供了显着的优势。

此外,它与语言无关,可以在任何环境中运行,使其成为服务器到服务器通信的理想选择。

我不会深入研究它的完整解释,但这里是 gRPC 的一般链接。我将提供实践教程

Go gRPC 客户端 

让我们想象一下,我们的 Go 是客户端,但对于前端应用程序 React、Svelte 等来说,它是服务器。

func getFirstArg() (string, error) {
    if len(os.Args) 



gRPC Communication Between Go and Python


作为示例,React 前端上传一个文件,Go 处理它,但我们需要来自 excel 的答案,我们将使用 GPT API。虽然可以用 Go 来完成,但另一方面 Python 有更多可以简化我们生活的软件包,例如 langchan_openai、pandas for excel 等等。


我们首先最好在您的 virtualenv .venv 中安装 gRPC

$ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
$ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
$ export PATH="$PATH:$(go env GOPATH)/bin"

接下来你应该在你的操作系统中安装protocol buffer,可以在此处安装。
让我们创建一个 proto 目录,您将在其中存储协议​​缓冲区文件,我将其命名为 excel.proto 并粘贴此:

syntax = "proto3";
option go_package = "client-gRPC/proto";
service ExcelService {
    rpc UploadFile(FileRequest) returns (FileResponse);
}
message FileRequest {
    string file_name = 1;
    bytes file_content = 2;
}
message FileResponse {
    bytes file_content = 1;
}

这个 gRPC 服务 ExcelService 允许客户端通过发送文件名称和内容来上传文件。服务器以相同的文件内容进行响应。 

对于 Go,在 Python 中传递 go_package 是必需的,不需要这一行。

如果您使用 VSCode,vscode-proto3 是一个很好的下载扩展。

完成所有这些之后,您可以生成原型文件,我更喜欢它与 prot 目录处于同一级别,为此运行此命令:

协议--go_out=。 --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative proto/excel.proto

如果成功生成两个文件,如果需要进行大量调整,则可以选择添加一个 Makefile 并将其定义为 proto 上命令。

import (
    ....

    "google.golang.org/grpc"
    pb "client-gRPC/proto"
    "github.com/xuri/excelize/v2"
)

func main() {
    ....

    conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
    if err != nil {
        log.Fatalf("Failed to connect to gRPC server: %v", err)
    }
    defer conn.Close()

    client := pb.NewExcelServiceClient(conn)

    req := &pb.FileRequest{
        FileName:    filePath,
        FileContent: fileData,
    }

    res, err := client.UploadFile(context.Background(), req)
    if err != nil {
        log.Fatalf("Failed to upload file: %v", err)
    }

    outputFile := "output.xlsx"
    err = saveBytesAsExcel(outputFile, res.FileContent)
    if err != nil {
        log.Fatalf("Failed to save bytes as Excel file: %v", err)
    }

    fmt.Printf("Excel file saved as: %s\n", outputFile)
}

func saveBytesAsExcel(filePath string, fileContent []byte) error {
    f, err := excelize.OpenReader(bytes.NewReader(fileContent))
    if err != nil {
        return fmt.Errorf("failed to open Excel file: %v", err)
    }

    if err := f.SaveAs(filePath); err != nil {
        return fmt.Errorf("failed to save Excel file: %v", err)
    }
    return nil
}

我们建立一个连接来监听 50051,它将成为我们的 Python 服务器,&pb.FileRequest 是之前使用 proto 命令生成的,现在我们正在导入方法。如果你跑步你会收到?由于Python服务器尚未建立。

Failed to upload file: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing: dial tcp 127.0.0.1:50051: connect: connection refused"

Python gRPC 服务器

由于 python 将充当服务器,因此方法会略有不同,但本质上不需要包字段中的相同原始文件。让我们首先创建一个不带 gRPC 的基础 main.py,以便了解 GPT 如何填充 excel 中的问题。

import os
import openai
import pandas as pd
from dotenv import load_dotenv

def get_answer_from_gpt(apikey: str, question: str):
    openai.api_key = apikey
    response = openai.ChatCompletion.create(
        model="gpt-4",
        messages=[
            {"role": "system", "content": "You are a helpful assistant."},
            {"role": "user", "content": question}
        ]
    )
    return response['choices'][0]['message']['content'].strip()

def answer_questions_df(df: pd.DataFrame, apikey: str):
    answers = []

    for question in df.iloc[:, 0]: 
        answer = get_answer_from_gpt(apikey, question)
        answers.append(answer)
    return answers

if __name__ == "__main__":
    load_dotenv()

    openai_api_key = os.getenv("OPENAI_API_KEY", "OpenAI API key hasn't been set.")

    df = pd.read_excel('Book1.xlsx')

    df['Answer'] = answer_questions_df(df, openai_api_key

这是一个简单的脚本,可以回答 Go 发送给我们的问题,但由于专用的 openai 库,LOC 较少,这使得它变得更容易。


我们首先添加具有与上面相同的文件的原始目录,可以按照讨论删除选项部分。最好在您的 virtualenv 中安装 gRPC,然后按照我运行的原型生成安装“

python3 -m grpc_tools.protoc --proto_path=proto --python_out=proto --grpc_python_out=proto proto/excel.proto

与我的原始目录处于相同的lvl 记得添加 __init.py

文件已生成,让我们继续。

import io
import grpc
from proto import excel_pb2_grpc as excel_grpc
from proto import excel_pb2

class ExcelService(excel_grpc.ExcelServiceServicer):
    def UploadFile(self, request, context):
        try:
            # Convert bytes to a file-like object
            file_like_object = io.BytesIO(request.file_content)

            # Load the workbook from the file-like object
            workbook = openpyxl.load_workbook(file_like_object)

            # Access the first sheet (or use appropriate logic to get the sheet you need)
            sheet = workbook.active

            # Convert the sheet to a DataFrame
            data = sheet.values
            columns = next(data)  # Get the header row
            df = pd.DataFrame(data, columns=columns)

            print("Loaded DataFrame:")
            print(df.head())

            # Ensure that the DataFrame is not empty and has questions
            if df.empty or df.shape[1] 



我们定义服务器并添加 ExcelService 类,其中包含 proto 文件生成的方法。因为我们按字节接收文件,所以必须使用 io 字节读取器并开始进一步处理文件并填充第二列。

response = excel_pb2.FileResponse(file_content=output.read())

最后我们返回 ☝️ 供 Go 客户端接收。

为了能够在 python 中找到原始文件,您应该定义一个导出路径

导出 PYTHONPATH=$PYTHONPATH:mnt/c/own_dev/gRPC/server/proto

运行客户端和服务器

If all is good you can run

#First comes server

python3 -m main

#Then client

go run client.go Book1.xlsx

您应该在 Go 客户端获得更新的 .xlsx 文件。

结论

在本文中,我们探讨了在 Python 服务器和 Go 客户端之间设置 gRPC 通信的基础知识。通过利用 gRPC,我们建立了一种无缝方式,将 Excel 文件从 Go 应用程序发送到 Python 服务器,使用 OpenAI 的 GPT API 处理文件,并将修改后的文件返回到 Go 客户端。

版本聲明 本文轉載於:https://dev.to/mozes721/grpc-communication-between-go-and-python-40i3?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 使用純 Javascript 只需幾行即可實現飛向購物車的動畫。
    使用純 Javascript 只需幾行即可實現飛向購物車的動畫。
    最近,我偶然發現了一個舊教程,展示了使用 jQuery 實現飛行到購物車的動畫。我想透過使用純 JavaScript 實現相同的效果來挑戰自己。 我創建了一個包含產品和購物車圖示的簡單佈局。樣式並不重要,所以我們不會在這裡討論它。 訣竅是複製產品圖像,將其添加到產品元素之前。然後計算克隆圖像和購...
    程式設計 發佈於2024-11-08
  • Bokeh 是一個有趣的 Python 資料視覺化資料工具
    Bokeh 是一個有趣的 Python 資料視覺化資料工具
    資料視覺化在解釋大量資訊方面發揮關鍵作用。 Bokeh 等工具已成為建立互動式儀表板和報告的流行解決方案。每個工具都具有獨特的優勢,具體取決於您專案的複雜性和您首選的程式語言。在本文中,我們將深入研究每個工具,然後專注於 Bokeh,包括實踐範例和雲端中的部署。 以便... 什麼是散景? Bok...
    程式設計 發佈於2024-11-08
  • django-components v 模板現在與 Vue 或 React 相當
    django-components v 模板現在與 Vue 或 React 相當
    嘿,我是 Juro,我是 django-components 的維護者之一。在 v0.90-0.94 版本中,我們添加了一些功能,使模板中的元件使用更加靈活,類似於 JSX / Vue。 (此資訊已經有點過時了(一個月前發布;最新的是v0.101),因為我正忙著添加對JS / CSS 變數、Typ...
    程式設計 發佈於2024-11-08
  • 如何在 Go 中解密 AES ECB 模式加密?
    如何在 Go 中解密 AES ECB 模式加密?
    Go 中的AES ECB 加密Go 中的AES ECB 加密package main import ( "crypto/aes" "fmt" ) func decryptAes128Ecb(data, key []byte) []byte { ...
    程式設計 發佈於2024-11-08
  • 在 GitHub-echo 中實現 TOML 配置支持
    在 GitHub-echo 中實現 TOML 配置支持
    介绍 最近,我有机会通过添加对 TOML 配置文件的支持来增强 github-echo 命令行工具。此功能允许用户在 .github-echo-config.toml 文件中设置持久默认选项,从而减少每次使用该工具时手动输入重复配置的需要。在这篇文章中,我将向您介绍我在该功能上的经...
    程式設計 發佈於2024-11-08
  • 如何使用 SimpleXML 和 DOMDocument 刪除 XPath 節點?
    如何使用 SimpleXML 和 DOMDocument 刪除 XPath 節點?
    SimpleXML:刪除XPath 節點在本文中,我們將探討如何使用以下方法有效地從XML 文件中刪除父節點: SimpleXML 和XPath。 了解 SimpleXML限制提供的程式碼嘗試使用 SimpleXML 在透過 XPath 找到父節點後刪除它。然而,SimpleXML 的 unset(...
    程式設計 發佈於2024-11-08
  • 建立一個 React Hook 以任意角度旋轉影像
    建立一個 React Hook 以任意角度旋轉影像
    在Web開發中,您可能需要旋轉影像,這在CSS中很容易做到。像這樣的簡單程式碼變換:rotate(90deg);。但是如果我們想用 JS 來做呢? TLDR 將圖像繪製到瀏覽器環境中的畫布上並旋轉它。但在此之前,我們需要做一些數學運算來保持原始影像的長寬比。 核 ...
    程式設計 發佈於2024-11-08
  • Lithe 中間件:它是如何運作的以及如何創建自己的中間件
    Lithe 中間件:它是如何運作的以及如何創建自己的中間件
    中间件提供了一种方便的机制来检查和过滤进入应用程序的 HTTP 请求。 例如,Lithe 包含检查用户是否经过身份验证的中间件。如果没有,中间件会将用户重定向到登录屏幕。如果用户通过身份验证,中间件将允许请求继续。 中间件如何在 Lithe 中工作 在 Lithe 中,中间件是能够访...
    程式設計 發佈於2024-11-08
  • 如何在 JavaScript 中建立具有重複元素的陣列?
    如何在 JavaScript 中建立具有重複元素的陣列?
    JavaScript 中重複元素的數組創建具有多次重複的相同元素的數組在各種編程場景中至關重要。在 Python 中,這可以透過列表乘法來實現,如 [2] * 5 所示。但是,此功能在 JavaScript 陣列中不能直接使用。 自訂函數方法為了滿足這種需求,一種方法是建立自訂函數,例如問題中提供的...
    程式設計 發佈於2024-11-08
  • ## MySQL 中的 LIKE 與 LOCATE:哪個運算子是效能之王?
    ## MySQL 中的 LIKE 與 LOCATE:哪個運算子是效能之王?
    MySQL LIKE 與LOCATE 效能比較在MySQL 中查找資料時,你可能會想知道LIKE 和LOCATE 哪個運算子效率更高?本文探討了這兩個運算子之間的效能差異。 在典型的使用場景中,LIKE 比 LOCATE 稍快。這主要是因為 LIKE 不像 LOCATE 那樣執行與 0 的額外比較。...
    程式設計 發佈於2024-11-08
  • 如何使用 PHP 更新多個 MySQL 行的表單資料?
    如何使用 PHP 更新多個 MySQL 行的表單資料?
    使用表單資料更新多個MySQL 行在Web 開發中,通常有一個表單,使用者可以在其中編輯資料庫中的記錄。常見的情況是使用修改後的資料更新同一個表中的多行。這可以使用 PHP 和 MySQL 來實作。 表單結構與資料擷取初始表單負責呈現要編輯的資料。在此範例中,表單從資料庫中擷取具有特定 GALLER...
    程式設計 發佈於2024-11-08
  • 為什麼我不能在 Go 中將 []byte 分配給字串?
    為什麼我不能在 Go 中將 []byte 分配給字串?
    了解位元組分配錯誤:無法將[]byte 指派給字串在嘗試讀取資料夾中的檔案時,遇到了錯誤嘗試讀取檔案內容時,「無法在多重賦值中將[]byte 指派給z(字串類型)」。讓我們深入研究這個錯誤背後的原因。 理解多重賦值當在一行中為多個變數賦值時,如程式碼所示:z, err := ioutil.ReadF...
    程式設計 發佈於2024-11-08
  • 如何使用 React 和 Typescript 建立自訂表格元件(第 2 部分)
    如何使用 React 和 Typescript 建立自訂表格元件(第 2 部分)
    介绍 耶! ?您已经完成了这个由两部分组成的系列的最后一部分!如果您还没有查看第 1 部分,请先停在此处并完成第 1 部分。别担心,我们会等你回来! ? 在第 1 部分中,我们构建了 CustomTable 组件。您可以在这里看到它的实际效果。 在第二部分中,我们将扩展该组件以添加...
    程式設計 發佈於2024-11-08
  • 使用 TypeScript 和 ioredis 在 Node.js 中建立高效能快取管理器
    使用 TypeScript 和 ioredis 在 Node.js 中建立高效能快取管理器
    使用基於 ioredis 建構的多功能、易於使用的快取管理器來提升 Node.js 應用程式的效能。簡化快取、優化效率並簡化操作。 我根據自己的需求開發了一個基於 ioredis 的類,重點關注易用性和性能。它包括 TypeScript 支持,旨在實現簡單使用和高效操作。它仍然可以進一步改進和優化...
    程式設計 發佈於2024-11-08
  • 超類別引用和子類別對象
    超類別引用和子類別對象
    Java 是一種強型別語言。 標準轉換和自動升級適用於原始型別。 嚴格執行型別相容性。 通常,一個類別的引用變數不能引用另一個類別的物件。 即使類別 X 和 Y 在結構上相同,也不可能將 X 的引用分配給 Y 的對象,因為類型不同。 一般來說,物件引用變數只能引用其類型的物件。 型別強...
    程式設計 發佈於2024-11-08

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3